﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HA.ModFlow.Domain.FileLayer;


using HA.ModFlow.Infrastructure;

namespace HA.ModFlow.Domain.DomainLayer
{

    [Serializable]
   public class LPFData:FlowDataBase,ICloneable
    {
        public LPFData(InnerFlowV2 parent):base(parent)
        {


            this.InitGridData();

 

        }

        public void OnLPFDataChanged()
        {
            if (this.LPFDataChanged != null)
                this.LPFDataChanged(null, null);
        }


        [field: NonSerialized]
        public event EventHandler LPFDataChanged;

        CellCenterDataSet3d _hani;

        /// <summary>
        /// 列方向水力传导系数
        /// </summary>
        public CellCenterDataSet3d Hani
        {
            get { return _hani; }
            set { _hani = value; }
        }

        CellCenterDataSet3d _ss;

        /// <summary>
        /// 至少存在一个瞬态应力期时输入此数据
        /// </summary>
        public CellCenterDataSet3d Ss
        {
            get { return _ss; }
            set { _ss = value; }
        }


        CellCenterDataSet3d _sy;

        /// <summary>
        /// 至少存在一个瞬态应力期，且层类型不是0 （不是承压层） （所有可转换层）
        /// </summary>
        public CellCenterDataSet3d Sy
        {
            get { return _sy; }
            set { _sy = value; }
        }


        CellCenterDataSet3d _vka;

        /// <summary>
        /// 垂直传导系数或者是与水平系数的比例
        /// </summary>
        public CellCenterDataSet3d Vka
        {
            get { return _vka; }
            set { _vka = value; }
        }


        CellCenterDataSet3d _vkcb;

        /// <summary>
        /// 隔水板的垂直渗透率，因为最后一层有隔水板也没有意义，所以最底层 的一层不需要输入此数据
        /// </summary>
        public CellCenterDataSet3d Vkcb
        {
            get { return _vkcb; }
            set { _vkcb = value; }
        }



        //公用参数部分

        #region 层属性区

       



        List<LPFLayer> _layers = new List<LPFLayer>();

        public List<LPFLayer> Layers
        {
            get { return _layers; }
            set { _layers = value; }
        }



        #endregion

        #region 单独属性区

        /// <summary>
        /// 
        /// </summary>


        int _ILPFCB = 0;

        /// <summary>
        /// cellbycell写入标志
        /// </summary>
        public int ILPFCB
        {
            get { return _ILPFCB; }
            set { _ILPFCB = value; }
        }




        bool _isStorageCoefficient;

        /// <summary>
        /// 储水
        /// </summary>
        public bool IsStorageCoefficient
        {
            get { return _isStorageCoefficient; }
            set { _isStorageCoefficient = value; }
        }


        bool _isConstantCV;

        /// <summary>
        /// 单元
        /// </summary>
        public bool IsConstantCV
        {
            get { return _isConstantCV; }
            set { _isConstantCV = value; }
        }


        bool _isThickStrt;
        /// <summary>
        /// 厚度方法
        /// </summary>
        public bool IsThickStrt
        {
            get { return _isThickStrt; }
            set { _isThickStrt = value; }
        }

        bool _isNoCVCorrection;

        /// <summary>
        /// 垂直流动不修正
        /// </summary>
        public bool IsNoCVCorrection
        {
            get { return _isNoCVCorrection; }
            set { _isNoCVCorrection = value; }
        }


        int _NPLPF;

        /// <summary>
        /// lpf参数的数量
        /// </summary>
        public int NPLPF
        {
            get { return _NPLPF; }
            set { _NPLPF = value; }
        }


        #endregion

        public void OnIboundsChanged(List<int[,]> iBound)
        {
            if (this._hani != null)
                this._hani.SetIBounds(iBound);
            if (this._ss != null)
                this._ss.SetIBounds(iBound);
            if (this._sy != null)
                this._sy.SetIBounds(iBound);
            if (this._vka != null)
                this._vka.SetIBounds(iBound);
            if (this._vkcb != null)
                this._vkcb.SetIBounds(iBound);
        }


        public PLayerPropertyFlow ToLPFPack()
        {
            int layerNum = this._layers.Count;
            PLayerPropertyFlow ppf = new PLayerPropertyFlow(layerNum);


            ppf.IsHaveTransient = this.Parent.IsHaveTransient;



            ppf.HDRY = this.Parent.HDRY;
            ppf.WETFCT = this.Parent.WETFCT;
            ppf.IWETIT = this.Parent.IWETIT;
            ppf.IHDWET = this.Parent.IHDWET;

          

          

            if (this.IsStorageCoefficient)
            {
                ppf.OPTIONS += "STORAGECOEFFICIENT";
            }
            if (this.IsConstantCV)
            {
                ppf.OPTIONS += "CONSTANTCV";

            }
            if (this.IsThickStrt)
            {
                ppf.OPTIONS += "THICKSTRT";
            }

            if (this.IsNoCVCorrection)
            {
                ppf.OPTIONS += "NOCVCORRECTION";
            }





                
            this.Parent.Hk.GetAllGridData(ppf.HK);


         

            this.Hani.GetAllGridData(ppf.HANI);


          

            this.Vka.GetAllGridData(ppf.VKA);

         

            this.Vkcb.GetAllGridData(ppf.VKCB);


          

            this.Parent.WetDry.GetAllGridData(ppf.WETDRY);


          

            this.Ss.GetAllGridData(ppf.Ss);

           

            this.Sy.GetAllGridData(ppf.Sy);


            //List<double[,]> hk = new List<double[,]>();

            //this.Parent.Hk.GetAllGridData(hk);


            //List<double[,]> hani = new List<double[,]>();

            //this.Hani.GetAllGridData(hani);


            //List<double[,]> vka = new List<double[,]>();

            //this.Vka.GetAllGridData(vka);

            //List<double[,]> vkcb = new List<double[,]>();

            //this.Vkcb.GetAllGridData(vkcb);


            //List<double[,]> wet = new List<double[,]>();

            //this.Parent.WetDry.GetAllGridData(wet);


            //List<double[,]> ss = new List<double[,]>();

            //this.Ss.GetAllGridData(ss);

            //List<double[,]> sy = new List<double[,]>();

            //this.Sy.GetAllGridData(sy);



          


            //
            int i = 0;
            foreach (LPFLayer layer in this._layers)
            {

                

            
                switch (layer.LayerType)
                {
                    case LPFLAYERTYPE.CONFINED: ppf.LayerTypes[i] = 0;
                        break;
                    case LPFLAYERTYPE.CONVERTIBLE: ppf.LayerTypes[i] = 1;
                        break;
                    case LPFLAYERTYPE.CONVERTIBLEONTHICKSTRT: ppf.LayerTypes[i] = -1;
                        break;
                }

                //ppf.LayerTypes[i] = (int)(layer.LpfLayer.LayerType)-1;
                ppf.LAYAVG[i] = layer.LAYAVG;
                ppf.LAYVKA[i] = layer.LAYVKAIsValue ? 1 : 0;
                ppf.CHANI[i] = layer.CHANI;


                //修正湿化为统一控制
                //ppf.LAYWET[i] = layer.CanWet ? 1 : 0;

                //当层类型为confined 时候，需要指定为不可湿化

                int wet= this.Parent.CanWet ? 1 : 0;
                if (layer.LayerType==LPFLAYERTYPE.CONFINED)
                {
                    wet = 0;
                    
                }

   

                ppf.LAYWET[i] =wet;



                i++;


            }


            return ppf;

           

        }

        public object Clone()
        {
            return this.MemberwiseClone();
        }

        public LPFData CloneWithoutDataset()
        {

            LPFData data=(LPFData) this.MemberwiseClone();

            data.Layers = new List<LPFLayer>();

            foreach (LPFLayer item in this.Layers)
	        {
               data.Layers.Add ((LPFLayer)item.Clone());
		 
	        }

           



            return data;

        }

       




        #region 内部方法

        protected void InitGridData()
        {
            double[, ,] hani = new double[this.Parent.GridData.RowsCount, this.Parent.GridData.ColsCount, this.Parent.GridData.LayersCount];
            this.Hani = new CellCenterDataSet3d(hani, this.Parent.GridData.WaterGrid.GetIBounds());
            this.Hani.Label = "Hani";
            this.Hani.ConstantData(1);

            double[, ,] ss = new double[this.Parent.GridData.RowsCount, this.Parent.GridData.ColsCount, this.Parent.GridData.LayersCount];
            this.Ss = new CellCenterDataSet3d(ss, this.Parent.GridData.WaterGrid.GetIBounds());
            this.Ss.Label = "Ss";

            double[, ,] sy = new double[this.Parent.GridData.RowsCount, this.Parent.GridData.ColsCount, this.Parent.GridData.LayersCount];
            this.Sy = new CellCenterDataSet3d(sy, this.Parent.GridData.WaterGrid.GetIBounds());
            this.Sy.Label = "Sy";

            double[, ,] vka = new double[this.Parent.GridData.RowsCount, this.Parent.GridData.ColsCount, this.Parent.GridData.LayersCount];
            this.Vka = new CellCenterDataSet3d(vka, this.Parent.GridData.WaterGrid.GetIBounds());
            this.Vka.Label = "Vka";
            this.Vka.ConstantData(3);



            double[, ,] vkcb = new double[this.Parent.GridData.RowsCount, this.Parent.GridData.ColsCount, this.Parent.GridData.LayersCount];
            this.Vkcb = new CellCenterDataSet3d(vkcb, this.Parent.GridData.WaterGrid.GetIBounds());
            this.Vkcb.Label = "Vkcb";


          
            this.Layers.Clear ();

            for (int i = 0; i < this.Parent.GridData.LayersCount; i++)
            {
                LPFLayer layer = new LPFLayer(this.Parent.GridData.RowsCount,this.Parent.GridData.ColsCount);

                this.Layers.Add(layer);
                
            }





        }

       #endregion


       
    }
}
